```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Kafka Leader 故障处理深度解析</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            line-height: 1.6;
            color: #333;
            background-color: #f8fafc;
        }
        .hero {
            background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
            color: white;
        }
        .section-title {
            position: relative;
            padding-bottom: 0.5rem;
        }
        .section-title:after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 0;
            width: 3rem;
            height: 4px;
            background: #4f46e5;
            border-radius: 2px;
        }
        .card {
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            border-radius: 0.5rem;
            overflow: hidden;
        }
        .card:hover {
            transform: translateY(-4px);
            box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
        }
        .highlight-box {
            border-left: 4px solid #4f46e5;
            background-color: rgba(79, 70, 229, 0.05);
        }
        .drop-cap::first-letter {
            float: left;
            font-size: 3.5rem;
            line-height: 0.8;
            margin: 0.15em 0.1em 0 0;
            color: #4f46e5;
            font-weight: 700;
        }
        .timeline-item:not(:last-child):after {
            content: '';
            position: absolute;
            left: 0.5rem;
            top: 2rem;
            bottom: -1.5rem;
            width: 2px;
            background: #e2e8f0;
        }
    </style>
</head>
<body class="antialiased">
    <!-- Hero Section -->
    <section class="hero py-20 px-6 md:px-0">
        <div class="max-w-4xl mx-auto text-center">
            <div class="inline-block px-3 py-1 mb-4 text-xs font-semibold text-indigo-100 bg-indigo-800 rounded-full">
                <i class="fas fa-server mr-1"></i> Kafka 分布式系统
            </div>
            <h1 class="text-4xl md:text-5xl font-bold leading-tight mb-4">Kafka Leader 故障处理深度解析</h1>
            <p class="text-xl text-indigo-100 max-w-2xl mx-auto">
                当 Leader 宕机且 ISR 为空时的应急处理机制与最佳实践
            </p>
            <div class="mt-12">
                <div class="inline-flex bg-white bg-opacity-10 backdrop-blur-sm rounded-lg p-1">
                    <div class="px-3 py-2 rounded-md flex items-center">
                        <i class="fas fa-bolt text-yellow-300 mr-2"></i>
                        <span>高可用性</span>
                    </div>
                    <div class="px-3 py-2 rounded-md flex items-center">
                        <i class="fas fa-shield-alt text-green-300 mr-2"></i>
                        <span>数据一致性</span>
                    </div>
                    <div class="px-3 py-2 rounded-md flex items-center">
                        <i class="fas fa-chart-line text-blue-300 mr-2"></i>
                        <span>系统监控</span>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="max-w-4xl mx-auto px-6 md:px-0 py-12">
        <!-- Introduction -->
        <section class="mb-16">
            <p class="text-lg text-gray-600 mb-6 drop-cap">
                在分布式消息系统 Kafka 中，Leader 副本负责处理所有读写请求，当 Leader 宕机且 ISR（In-Sync Replicas）为空时，系统将面临严重的数据可用性问题。这种异常情况需要及时诊断并采取正确的恢复措施，以确保消息系统的稳定性和数据一致性。
            </p>
            <div class="bg-white rounded-xl shadow-sm p-6 mb-8">
                <div class="flex items-start">
                    <div class="flex-shrink-0 h-12 w-12 rounded-lg bg-indigo-50 flex items-center justify-center text-indigo-600">
                        <i class="fas fa-exclamation-triangle text-xl"></i>
                    </div>
                    <div class="ml-4">
                        <h3 class="text-lg font-semibold text-gray-900">关键问题</h3>
                        <p class="text-gray-600 mt-1">当 ISR 为空时，意味着没有副本能够接替 Leader 角色，这通常会导致分区不可用，客户端可能遇到写入或读取失败的情况。</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Cause Analysis -->
        <section class="mb-16">
            <h2 class="text-2xl font-bold text-gray-800 mb-6 section-title">
                <i class="fas fa-search mr-2 text-indigo-500"></i>Leader 宕机原因分析
            </h2>
            
            <div class="grid md:grid-cols-2 gap-6">
                <div class="card bg-white p-6 shadow-sm">
                    <div class="flex items-center mb-4">
                        <div class="flex-shrink-0 h-10 w-10 rounded-lg bg-red-50 flex items-center justify-center text-red-600">
                            <i class="fas fa-hdd"></i>
                        </div>
                        <h3 class="ml-3 text-lg font-semibold">硬件故障</h3>
                    </div>
                    <p class="text-gray-600">
                        服务器硬件问题如磁盘故障、内存损坏、网络中断或电源故障会导致 Leader 副本突然不可用。这类故障通常需要人工干预修复或替换硬件。
                    </p>
                    <div class="mt-4 pt-4 border-t border-gray-100">
                        <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
                            <i class="fas fa-clock mr-1"></i> 恢复时间较长
                        </span>
                    </div>
                </div>
                
                <div class="card bg-white p-6 shadow-sm">
                    <div class="flex items-center mb-4">
                        <div class="flex-shrink-0 h-10 w-10 rounded-lg bg-purple-50 flex items-center justify-center text-purple-600">
                            <i class="fas fa-bug"></i>
                        </div>
                        <h3 class="ml-3 text-lg font-semibold">软件问题</h3>
                    </div>
                    <p class="text-gray-600">
                        Kafka 服务崩溃、操作系统内核问题、JVM OOM 或配置错误等软件层面的故障。这类问题可能通过重启服务或修复配置来解决。
                    </p>
                    <div class="mt-4 pt-4 border-t border-gray-100">
                        <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800">
                            <i class="fas fa-sync-alt mr-1"></i> 可能自动恢复
                        </span>
                    </div>
                </div>
            </div>
        </section>

        <!-- Handling Procedures -->
        <section class="mb-16">
            <h2 class="text-2xl font-bold text-gray-800 mb-6 section-title">
                <i class="fas fa-tools mr-2 text-indigo-500"></i>故障处理方法
            </h2>
            
            <!-- Timeline -->
            <div class="relative">
                <!-- Item 1 -->
                <div class="relative timeline-item pl-8 pb-8">
                    <div class="absolute left-0 top-0 h-4 w-4 rounded-full bg-indigo-500 border-4 border-indigo-100"></div>
                    <div class="card bg-white p-6 shadow-sm">
                        <h3 class="text-lg font-semibold text-gray-900 mb-2">故障检测与标记</h3>
                        <p class="text-gray-600">
                            Kafka 控制器通过 ZooKeeper 监视 Broker 状态，当检测到 Leader 宕机时，会将其标记为不可用状态。控制器会收到 Broker 故障通知，通常是通过 ZooKeeper 的临时节点失效触发。
                        </p>
                    </div>
                </div>
                
                <!-- Item 2 -->
                <div class="relative timeline-item pl-8 pb-8">
                    <div class="absolute left-0 top-0 h-4 w-4 rounded-full bg-indigo-500 border-4 border-indigo-100"></div>
                    <div class="card bg-white p-6 shadow-sm">
                        <h3 class="text-lg font-semibold text-gray-900 mb-2">ISR 恢复策略评估</h3>
                        <p class="text-gray-600">
                            控制器检查 ISR 列表，如果发现 ISR 为空，表示没有副本与旧 Leader 保持同步。此时系统需要决定是否等待副本恢复同步或从非 ISR 副本中选择新 Leader（取决于 <code>unclean.leader.election.enable</code> 配置）。
                        </p>
                    </div>
                </div>
                
                <!-- Item 3 -->
                <div class="relative timeline-item pl-8 pb-8">
                    <div class="absolute left-0 top-0 h-4 w-4 rounded-full bg-indigo-500 border-4 border-indigo-100"></div>
                    <div class="card bg-white p-6 shadow-sm">
                        <h3 class="text-lg font-semibold text-gray-900 mb-2">新 Leader 选举</h3>
                        <p class="text-gray-600">
                            如果允许 unclean leader 选举（默认禁止），则从存活副本中选择新 Leader，否则分区将保持不可用状态直到有副本恢复。选举基于 ZooKeeper 的分布式锁机制确保唯一性。
                        </p>
                    </div>
                </div>
                
                <!-- Item 4 -->
                <div class="relative timeline-item pl-8">
                    <div class="absolute left-0 top-0 h-4 w-4 rounded-full bg-indigo-500 border-4 border-indigo-100"></div>
                    <div class="card bg-white p-6 shadow-sm">
                        <h3 class="text-lg font-semibold text-gray-900 mb-2">数据同步与恢复</h3>
                        <p class="text-gray-600">
                            新 Leader 开始接受读写请求，并与 Followers 同步数据。Followers 从新 Leader 拉取消息进行同步，直到追上 Leader 的进度后加入 ISR 列表，恢复正常复制流程。
                        </p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Visualization -->
        <section class="mb-16">
            <h2 class="text-2xl font-bold text-gray-800 mb-6 section-title">
                <i class="fas fa-project-diagram mr-2 text-indigo-500"></i>Leader 选举流程可视化
            </h2>
            
            <div class="bg-white rounded-xl shadow-sm p-6">
                <div class="mermaid">
                    graph TD
                    A[Leader 宕机] --> B{ISR 是否为空?}
                    B -->|是| C[检查 unclean.leader.election 配置]
                    B -->|否| D[从 ISR 选举新 Leader]
                    C --> E{unclean.leader.election.enable?}
                    E -->|true| F[从存活副本选举新 Leader]
                    E -->|false| G[分区保持不可用]
                    F --> H[新 Leader 开始服务]
                    D --> H
                    G --> I[等待副本恢复]
                    I --> J[加入 ISR 后重新选举]
                    J --> H
                </div>
                <div class="mt-4 text-sm text-gray-500">
                    <i class="fas fa-info-circle mr-1 text-indigo-500"></i> 图示展示了 Kafka 在 Leader 宕机且 ISR 为空时的决策流程
                </div>
            </div>
        </section>

        <!-- System Stability -->
        <section>
            <h2 class="text-2xl font-bold text-gray-800 mb-6 section-title">
                <i class="fas fa-shield-alt mr-2 text-indigo-500"></i>系统稳定性与监控建议
            </h2>
            
            <div class="grid md:grid-cols-2 gap-6 mb-8">
                <div class="highlight-box p-6">
                    <h3 class="text-lg font-semibold text-gray-900 mb-3 flex items-center">
                        <i class="fas fa-bell text-indigo-500 mr-2"></i> 监控与报警配置
                    </h3>
                    <ul class="text-gray-600 space-y-2">
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>监控 Under Replicated Partitions 指标</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>设置 ISR 收缩警报（当 ISR 数量减少时）</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>监控 Controller 状态和 Leader 选举次数</span>
                        </li>
                    </ul>
                </div>
                
                <div class="highlight-box p-6">
                    <h3 class="text-lg font-semibold text-gray-900 mb-3 flex items-center">
                        <i class="fas fa-database text-indigo-500 mr-2"></i> 数据一致性保障
                    </h3>
                    <ul class="text-gray-600 space-y-2">
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>合理设置 <code>min.insync.replicas</code> 参数</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>禁用 <code>unclean.leader.election.enable</code> 避免数据丢失</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>定期验证端到端的数据完整性</span>
                        </li>
                    </ul>
                </div>
            </div>
            
            <div class="bg-indigo-50 rounded-xl p-6">
                <div class="flex">
                    <div class="flex-shrink-0">
                        <i class="fas fa-lightbulb text-2xl text-indigo-600"></i>
                    </div>
                    <div class="ml-3">
                        <h3 class="text-lg font-semibold text-indigo-800">最佳实践建议</h3>
                        <p class="mt-2 text-indigo-700">
                            生产环境建议至少配置 3 个副本，并将 <code>min.insync.replicas</code> 设置为 2。这样即使一个副本（包括 Leader）宕机，仍然能有至少一个同步副本可以接替 Leader 角色，避免 ISR 为空的情况发生。
                        </p>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
        
        // 添加微交互效果
        document.querySelectorAll('.card').forEach(card => {
            card.addEventListener('mouseenter', function() {
                this.querySelector('i')?.classList.add('animate-pulse');
            });
            card.addEventListener('mouseleave', function() {
                this.querySelector('i')?.classList.remove('animate-pulse');
            });
        });
    </script>
</body>
</html>
```